﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Client.Components.SearchPanelControls
{
    // V 1.0.1 - 2022-10-30 11:50:22
    // 1 修复日期值的更新
    // 2 新增2个依赖属性 [DP] DatePickerTextBox_Placeholder 与 DatePickerTextBox_PlaceholderColor
    //
    // V 1.0.0 - 2021-08-25 17:56:14
    // 重写并整理代码

    /// <summary>
    ///
    /// </summary>
    public partial class SearchConditionDateArea : SearchConditionBase
    {
        #region [DP] FromTitle

        /// <summary>
        /// FromTitle, 默认值: 从
        /// </summary>
        public static readonly DependencyProperty FromTitleProperty = DependencyProperty.Register
        (
            name: "FromTitle",
            propertyType: typeof(string),
            ownerType: typeof(SearchConditionDateArea),
            validateValueCallback: null,
            typeMetadata: new PropertyMetadata
            (
                defaultValue: "从",
                propertyChangedCallback: null,
                coerceValueCallback: null
            )
        );

        /// <summary>
        /// FromTitle, 默认值: 从
        /// </summary>
        public string FromTitle
        {
            get { return (string)GetValue(FromTitleProperty); }
            set { SetValue(FromTitleProperty, value); }
        }

        #endregion

        #region [DP] ToTitle

        /// <summary>
        /// ToTitle, 默认值: 至
        /// </summary>
        public static readonly DependencyProperty ToTitleProperty = DependencyProperty.Register
        (
            name: "ToTitle",
            propertyType: typeof(string),
            ownerType: typeof(SearchConditionDateArea),
            validateValueCallback: null,
            typeMetadata: new PropertyMetadata
            (
                defaultValue: "至",
                propertyChangedCallback: null,
                coerceValueCallback: null
            )
        );

        /// <summary>
        /// ToTitle, 默认值: 至
        /// </summary>
        public string ToTitle
        {
            get { return (string)GetValue(ToTitleProperty); }
            set { SetValue(ToTitleProperty, value); }
        }

        #endregion

        #region [DP] FromDate

        /// <summary>
        /// FromDate
        /// </summary>
        public static readonly DependencyProperty FromDateProperty = DependencyProperty.Register
        (
            name: "FromDate",
            propertyType: typeof(DateTime?),
            ownerType: typeof(SearchConditionDateArea),
            // validateValueCallback: null,
            validateValueCallback: new ValidateValueCallback((toValidate) =>
            {
                return true;
            }),
            typeMetadata: new FrameworkPropertyMetadata
            (
                defaultValue: null,
                flags: FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                propertyChangedCallback: onFromDate_PropertyChangedCallback,
                coerceValueCallback: null
            )
        );

        /// <summary>
        /// FromDate
        /// </summary>
        public DateTime? FromDate
        {
            get { return (DateTime?)GetValue(FromDateProperty); }
            set { SetValue(FromDateProperty, value); }
        }

        /// <summary>
        /// onFromDate_PropertyChangedCallback
        /// </summary>
        /// <param name="d"></param>
        /// <param name="e"></param>
        public static void onFromDate_PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is SearchConditionDateArea sdc)
            {
                if ((DateTime?)e.NewValue > sdc.ToDate && sdc.ToDate.HasValue)
                {
                    if (sdc.FromDateError != null)
                    {
                        sdc.FromDateError(d, e);
                    }
                    sdc.FromDate = (DateTime?)e.OldValue;
                    //sdc.ValidatingError = "结束日期不能小于开始日期";
                }
            }
        }

        #endregion

        #region [DP] ToDate

        /// <summary>
        /// ToDate
        /// </summary>
        public static readonly DependencyProperty ToDateProperty = DependencyProperty.Register
        (
            name: "ToDate",
            propertyType: typeof(DateTime?),
            ownerType: typeof(SearchConditionDateArea),
            validateValueCallback: null,
            typeMetadata: new FrameworkPropertyMetadata
            (
                defaultValue: null,
                flags: FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                propertyChangedCallback: onToDate_PropertyChangedCallback,
                coerceValueCallback: null
            )
        );

        /// <summary>
        /// ToDate
        /// </summary>
        public DateTime? ToDate
        {
            get { return (DateTime?)GetValue(ToDateProperty); }
            set { SetValue(ToDateProperty, value); }
        }

        /// <summary>
        /// onToDate_PropertyChangedCallback
        /// </summary>
        /// <param name="d"></param>
        /// <param name="e"></param>
        public static void onToDate_PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is SearchConditionDateArea sdc)
            {
                if ((DateTime?)e.NewValue < sdc.FromDate && sdc.FromDate.HasValue)
                {
                    if (sdc.ToDateError != null)
                    {
                        sdc.ToDateError(d, e);
                    }
                    sdc.ToDate = (DateTime?)e.OldValue;
                }
            }
        }

        #endregion

        #region [DP] Max~Min - From~ToDate

        /// <summary>
        /// MinFromDate
        /// </summary>
        public static readonly DependencyProperty MinFromDateProperty = DependencyProperty.Register("MinFromDate", typeof(DateTime?), typeof(SearchConditionDateArea));

        /// <summary>
        /// MinFromDate
        /// </summary>
        public DateTime? MinFromDate
        {
            get { return (DateTime?)GetValue(MinFromDateProperty); }
            set { SetValue(MinFromDateProperty, value); }
        }

        /// <summary>
        /// MaxFromDate
        /// </summary>
        public static readonly DependencyProperty MaxFromDateProperty = DependencyProperty.Register("MaxFromDate", typeof(DateTime?), typeof(SearchConditionDateArea));

        /// <summary>
        /// MaxFromDate
        /// </summary>
        public DateTime? MaxFromDate
        {
            get { return (DateTime?)GetValue(MaxFromDateProperty); }
            set { SetValue(MaxFromDateProperty, value); }
        }

        /// <summary>
        /// MinToDate
        /// </summary>
        public static readonly DependencyProperty MinToDateProperty = DependencyProperty.Register("MinToDate", typeof(DateTime?), typeof(SearchConditionDateArea));

        /// <summary>
        /// MinToDate
        /// </summary>
        public DateTime? MinToDate
        {
            get { return (DateTime?)GetValue(MinToDateProperty); }
            set { SetValue(MinToDateProperty, value); }
        }

        /// <summary>
        /// MaxToDate
        /// </summary>
        public static readonly DependencyProperty MaxToDateProperty = DependencyProperty.Register("MaxToDate", typeof(DateTime?), typeof(SearchConditionDateArea));

        /// <summary>
        /// MaxToDate
        /// </summary>
        public DateTime? MaxToDate
        {
            get { return (DateTime?)GetValue(MaxToDateProperty); }
            set { SetValue(MaxToDateProperty, value); }
        }

        #endregion

        #region [DP] TextBoxBackground

        /// <summary>
        /// TextBoxBackground
        /// </summary>
        public static readonly DependencyProperty TextBoxBackgroundProperty = DependencyProperty.Register
        (
            name: "TextBoxBackground",
            propertyType: typeof(System.Windows.Media.Brush),
            ownerType: typeof(SearchConditionDateArea),
            validateValueCallback: null,
            typeMetadata: new FrameworkPropertyMetadata
            (
                defaultValue: new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromRgb(245, 245, 245)),
                propertyChangedCallback: null,
                coerceValueCallback: null
            )
        );

        /// <summary>
        /// TextBoxBackground
        /// </summary>
        public System.Windows.Media.Brush TextBoxBackground
        {
            get { return (System.Windows.Media.Brush)GetValue(TextBoxBackgroundProperty); }
            set { SetValue(TextBoxBackgroundProperty, value); }
        }

        #endregion

        #region [DP] FromDateIsEnabled

        /// <summary>
        /// FromDateIsEnabled
        /// </summary>
        public static readonly DependencyProperty FromDateIsEnabledProperty = DependencyProperty.Register
        (
            name: "FromDateIsEnabled",
            propertyType: typeof(bool),
            ownerType: typeof(SearchConditionDateArea),
            validateValueCallback: null, // new ValidateValueCallback((toValidate) => { return true; }),
            typeMetadata: new PropertyMetadata
            (
                defaultValue: true,
                propertyChangedCallback: null,
                coerceValueCallback: null
            )
        );

        /// <summary>
        /// FromDateIsEnabled
        /// </summary>
        public bool FromDateIsEnabled
        {
            get { return (bool)GetValue(FromDateIsEnabledProperty); }
            set { SetValue(FromDateIsEnabledProperty, value); }
        }

        #endregion

        #region [DP] ToDateIsEnabled

        /// <summary>
        /// ToDateIsEnabled
        /// </summary>
        public static readonly DependencyProperty ToDateIsEnabledProperty = DependencyProperty.Register
        (
            name: "ToDateIsEnabled",
            propertyType: typeof(bool),
            ownerType: typeof(SearchConditionDateArea),
            validateValueCallback: null,
            typeMetadata: new PropertyMetadata
            (
                defaultValue: true,
                propertyChangedCallback: null,
                coerceValueCallback: null
            )
        );

        /// <summary>
        /// ToDateIsEnabled
        /// </summary>
        public bool ToDateIsEnabled
        {
            get { return (bool)GetValue(ToDateIsEnabledProperty); }
            set { SetValue(ToDateIsEnabledProperty, value); }
        }

        #endregion

        #region [DP] DatePickerTextBox_Placeholder

        /// <summary>
        /// DatePickerTextBox_Placeholder
        /// </summary>
        public static readonly DependencyProperty DatePickerTextBox_PlaceholderProperty = DependencyProperty.Register
        (
            name: "DatePickerTextBox_Placeholder",
            propertyType: typeof(string),
            ownerType: typeof(SearchConditionDateArea),
            validateValueCallback: null, // new ValidateValueCallback((toValidate) => { return true; }),
            typeMetadata: new FrameworkPropertyMetadata
            (
                defaultValue: "选择日期",
                // flags: FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                propertyChangedCallback: null,
                coerceValueCallback: null
            )
        );

        /// <summary>
        /// DatePickerTextBox_Placeholder
        /// </summary>
        public string DatePickerTextBox_Placeholder
        {
            get { return (string)GetValue(DatePickerTextBox_PlaceholderProperty); }
            set { SetValue(DatePickerTextBox_PlaceholderProperty, value); }
        }

        #endregion

        #region [DP] DatePickerTextBox_PlaceholderColor

        /// <summary>
        /// DatePickerTextBox_PlaceholderColor
        /// </summary>
        public static readonly DependencyProperty DatePickerTextBox_PlaceholderColorProperty = DependencyProperty.Register
        (
            name: "DatePickerTextBox_PlaceholderColor",
            propertyType: typeof(System.Windows.Media.Brush),
            ownerType: typeof(SearchConditionDateArea),
            validateValueCallback: null, // new ValidateValueCallback((toValidate) => { return true; }),
            typeMetadata: new FrameworkPropertyMetadata
            (
                defaultValue: System.Windows.Media.Brushes.Gray,
                // flags: FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
                propertyChangedCallback: null,
                coerceValueCallback: null
            )
        );

        /// <summary>
        /// DatePickerTextBox_PlaceholderColor
        /// </summary>
        public System.Windows.Media.Brush DatePickerTextBox_PlaceholderColor
        {
            get { return (System.Windows.Media.Brush)GetValue(DatePickerTextBox_PlaceholderColorProperty); }
            set { SetValue(DatePickerTextBox_PlaceholderColorProperty, value); }
        }

        #endregion

        /// <summary>
        /// 默认 DateTime 转换格式
        /// </summary>
        [Obsolete]
        public const string DateFormatDefaultValue = "yyyy-MM-dd";

        #region [DP] DateTimeStringFormat -- 弃用 暂时无法将值双向传递到 Converter 内

        /// <summary>
        /// DateTimeStringFormat, 默认值: yyyy-MM-dd
        /// </summary>
        [Obsolete]
        public static readonly DependencyProperty DateTimeStringFormatProperty = DependencyProperty.Register
        (
            name: "DateTimeStringFormat",
            propertyType: typeof(string),
            ownerType: typeof(SearchConditionDateArea),
            validateValueCallback: null, // new ValidateValueCallback((toValidate) => { return true; }),
            typeMetadata: new FrameworkPropertyMetadata
            (
                defaultValue: DateFormatDefaultValue,
                propertyChangedCallback: null,
                coerceValueCallback: null
            )
        );

        /// <summary>
        /// DateTimeStringFormat, 默认值: yyyy-MM-dd
        /// </summary>
        [Obsolete]
        public string DateTimeStringFormat
        {
            get { return (string)GetValue(DateTimeStringFormatProperty); }
            set { SetValue(DateTimeStringFormatProperty, value); }
        }

        #endregion

        /// <summary>
        /// SearchConditionDateArea 日期格式化字符串, 修改一处全局生效
        /// </summary>
        public static string s_DateFormatDefaultValue = "yyyy-MM-dd";

        /// <summary>
        /// Reset
        /// </summary>
        public override void Reset()
        {
            clearDatePicker(this.dpFrom);
            this.FromDate = null;

            clearDatePicker(this.dpTo);
            this.ToDate = null;
        }

        /// <summary>
        /// 若用户在界面中胡乱输入不正确的Text值后, 界面会标识红框提示异常
        /// 执行重置方法 (Reset) 若只对绑定的 FromDate ToDate 设置 null 值, 无法修改Text值
        /// 需要用本方法清除Text值
        /// </summary>
        /// <param name="dp"></param>
        void clearDatePicker(DatePicker dp)
        {
            dp.SelectedDate = null;
            dp.SelectedDate = DateTime.Today;
        }

        /// <summary>
        /// SearchConditionDateArea
        /// </summary>
        public SearchConditionDateArea()
        {
            InitializeComponent();
        }

        /// <summary>
        /// FromDateError
        /// </summary>
        public event PropertyChangedCallback FromDateError;

        /// <summary>
        /// ToDateError
        /// </summary>
        public event PropertyChangedCallback ToDateError;
    }

    /// <summary>
    /// DatePickerTextBox_MultiValueConverter
    /// </summary>
    public class DatePickerTextBox_MultiValueConverter : System.Windows.Data.IMultiValueConverter
    {
        /// <summary>
        /// Convert
        /// </summary>
        /// <param name="values"></param>
        /// <param name="targetType"></param>
        /// <param name="parameter"></param>
        /// <param name="culture"></param>
        /// <returns></returns>
        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            object value0 = values[0];

            if (value0 == null)
            {
                return string.Empty;
            }

            return ((DateTime)value0).ToString(SearchConditionDateArea.s_DateFormatDefaultValue);
        }

        /// <summary>
        /// ConvertBack
        /// </summary>
        /// <param name="value"></param>
        /// <param name="targetTypes"></param>
        /// <param name="parameter"></param>
        /// <param name="culture"></param>
        /// <returns></returns>
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
        {
            var r = new object[1];

            if (value != null && string.IsNullOrWhiteSpace(value.ToString()) == false)
            {
                try
                {
                    r[0] = System.Convert.ToDateTime(value.ToString());
                }
                catch (Exception)
                {
                    r[0] = null;
                }
            }
            else
            {
                r[0] = null;
            }

            return r;
        }
    }
}